package com.xuanxu.blogs.module.article.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xuanxu.blogs.module.article.entity.dao.ArticleClassifyDao;
import com.xuanxu.blogs.module.article.entity.dao.ArticleClassifyIntermediateDao;
import com.xuanxu.blogs.module.article.entity.dao.ArticleContentDao;
import com.xuanxu.blogs.module.article.entity.dao.ArticleDao;
import com.xuanxu.blogs.module.article.entity.po.Article;
import com.xuanxu.blogs.module.article.mapper.ArticleMapper;
import com.xuanxu.blogs.module.article.service.ArticleClassifyIntermediateService;
import com.xuanxu.blogs.module.article.service.ArticleClassifyService;
import com.xuanxu.blogs.module.article.service.ArticleContentService;
import com.xuanxu.blogs.module.article.service.ArticleService;
import com.xuanxu.blogs.module.user.client.admin.AdminUserClient;
import com.xuanxu.blogs.module.user.entity.dto.admin.AdminUserDto;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author XuanXu
 * @version 1.0
 * @date 2024-08-23 13:00
 */
@Service
@RequiredArgsConstructor
public class ArticleServiceImpl implements ArticleService {
    private final ArticleMapper articleMapper;
    private final ArticleClassifyIntermediateService articleClassifyIntermediateService;
    private final ArticleContentService articleContentService;
    private final ArticleClassifyService articleClassifyService;
    private final AdminUserClient adminUserClient;

    @Override
    public IPage<ArticleDao> pageSelectArticle(Long currentPage, Long pageSize, ArticleDao articleDao) {
        LambdaQueryWrapper<Article> articleLambdaQueryWrapper = constructionSelectCondition(articleDao);

        IPage<Article> articlePage = articleMapper.selectPage(new Page<>(currentPage, pageSize), articleLambdaQueryWrapper);
        IPage<ArticleDao> articleDaoPage = new Page<>();
        BeanUtil.copyProperties(articlePage, articleDaoPage);

        if (articlePage != null) {
            List<ArticleDao> articleDaoList = BeanUtil.copyToList(articlePage.getRecords(), ArticleDao.class);
            articleDaoList = getArticleOtherAttribute(articleDaoList);
            articleDaoPage.setRecords(articleDaoList);
        }

        return articleDaoPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateArticleByArticleId(ArticleDao articleDao) {
        if (articleDao == null) {
            return false;
        }

        LambdaUpdateWrapper<Article> articleLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        articleLambdaUpdateWrapper.set(articleDao.getArticleStatus() != null, Article::getArticleStatus, articleDao.getArticleStatus());
        articleLambdaUpdateWrapper.set(StrUtil.isNotEmpty(articleDao.getArticleAuditFailMessage()), Article::getArticleAuditFailMessage, articleDao.getArticleAuditFailMessage());
        articleLambdaUpdateWrapper.eq(Article::getArticleId, articleDao.getArticleId());
        int updateNumber = articleMapper.update(new Article(), articleLambdaUpdateWrapper);

        return updateNumber > 0;
    }

    /**
     * 获取文章的其他属性
     * @param articleDaoList 文章列表
     * @return List<ArticleDao>
     */
    private List<ArticleDao> getArticleOtherAttribute(List<ArticleDao> articleDaoList) {
        if (articleDaoList == null || articleDaoList.isEmpty()) {
            return articleDaoList;
        }

        articleDaoList = articleDaoList.stream().peek(articleDao -> {
            getArticleContent(articleDao);
            getArticleClassify(articleDao);
            getArticleAuthor(articleDao);
        }).collect(Collectors.toList());

        return articleDaoList;
    }

    /**
     * 获取文章创建的用户
     * @param articleDao 文章
     */
    private void getArticleAuthor(ArticleDao articleDao) {
        if (articleDao == null || articleDao.getUserId() == null) {
            return;
        }
        ResponseEntity<AdminUserDto> adminUserDtoResponseEntity = adminUserClient.selectUserByUserId(articleDao.getUserId());
        AdminUserDto adminUserDto = adminUserDtoResponseEntity.getBody();
        articleDao.setUser(adminUserDto);
    }

    /**
     * 获取文章分类
     * @param articleDao 文章 dao
     */
    private void getArticleClassify(ArticleDao articleDao) {
        if (articleDao == null) {
            return;
        }

        List<ArticleClassifyIntermediateDao> articleClassifyIntermediateDaoList = articleClassifyIntermediateService.selectArticleClassifyIntermediateByArticleId(articleDao.getArticleId());
        if (articleClassifyIntermediateDaoList == null || articleClassifyIntermediateDaoList.isEmpty()) {
            return;
        }

        List<Long> articleClassifyIdList = articleClassifyIntermediateDaoList.stream()
                .map(ArticleClassifyIntermediateDao::getArticleClassifyId)
                .collect(Collectors.toList());
        List<ArticleClassifyDao> articleClassifyDaoList = articleClassifyService.selectArticleClassifyByArticleClassifyId(articleClassifyIdList);
        articleDao.setArticleClassifyList(articleClassifyDaoList);
    }

    /**
     * 获取文章对应的文章内容
     * @param articleDao 文章
     */
    private void getArticleContent(ArticleDao articleDao) {
        if (articleDao == null) {
            return;
        }

        ArticleContentDao articleContentDao = articleContentService.selectArticleContentByArticleId(articleDao.getArticleId());
        if (articleContentDao != null) {
            articleDao.setArticleContent(articleContentDao.getArticleContent());
        }
    }

    /**
     * 构建查询条件
     * @param articleDao 查询条件
     * @return LambdaQueryWrapper<Article>
     */
    private LambdaQueryWrapper<Article> constructionSelectCondition(ArticleDao articleDao) {
        LambdaQueryWrapper<Article> articleLambdaQueryWrapper = new LambdaQueryWrapper<>();

        if (articleDao == null) {
            return articleLambdaQueryWrapper;
        }

        articleLambdaQueryWrapper.eq(articleDao.getArticleStatus() != null, Article::getArticleStatus, articleDao.getArticleStatus());

        // 查询文章分类关联的文章
        List<Long> articleClassifyIdList = articleDao.getArticleClassifyIdList();
        if (articleClassifyIdList != null && !articleClassifyIdList.isEmpty()) {
            List<ArticleClassifyIntermediateDao> articleClassifyIntermediateDaoList = articleClassifyIntermediateService.selectArticleClassifyIntermediateByArticleClassifyId(articleClassifyIdList);
            if (articleClassifyIntermediateDaoList != null && !articleClassifyIntermediateDaoList.isEmpty()) {
                Set<Long> articleIdList = articleClassifyIntermediateDaoList.stream()
                        .map(ArticleClassifyIntermediateDao::getArticleId)
                        .collect(Collectors.toSet());
                articleLambdaQueryWrapper.in(Article::getArticleId, articleIdList);
            }
        }

        return articleLambdaQueryWrapper;
    }
}
